package com.fubowen.api.extension

import com.squareup.moshi.Moshi
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import java.util.concurrent.TimeUnit

const val TIMEOUT = 30000L
const val CONTENT_TYPE = "Content-Type"
const val APPLICATION_JSON = "application/json"
const val CHARSET_UTF_8 = "charset=utf-8"

val httpClient = OkHttpClient.Builder().readTimeout(TIMEOUT, TimeUnit.MILLISECONDS).build()

fun fetchGet(url: String) = httpClient.newCall(Request.Builder().url(url).get().build()).execute()
fun fetchPost(url: String, data: String): Response {

    val mediaType = "$APPLICATION_JSON;$CHARSET_UTF_8".toMediaType()
    val json = data.toRequestBody(mediaType)
    val request = Request.Builder()
        .addHeader(CONTENT_TYPE, APPLICATION_JSON)
        .url(url)
        .post(json)
        .build()
    return httpClient.newCall(request).execute()
}

fun <T> retry(options: Options, block: () -> T): T? {
    for (i in 0 until options.tryCount) {
        try {
            return block()
        } catch (e: Exception) {
            val dd = e.message
        }
    }
    return null
}

inline fun <reified T> Response.toObject(): T? {
    return this.body.string().toObject()
}

inline fun <reified T> String.toObject(): T? {
    val moshi = Moshi.Builder().build()
    return moshi.adapter(T::class.java).fromJson(this)
}

inline fun <reified T> T.toJson(): String {
    val moshi = Moshi.Builder().build()
    return moshi.adapter(T::class.java).toJson(this)
}

data class Options(
    var tryCount: Int = 3,
    var timeout: Long = TIMEOUT,
)